<template>
  <div
    v-if="!isHiddenByMutex"
    class="form-component"
    :class="{ selected: isSelected }"
    :style="componentStyle"
    @click="handleClick"
    @focus="handleFocus"
    @blur="handleBlur"
  >
    <!-- 输入框 -->
    <el-form-item
      v-if="component.type === 'input'"
      :label="component.props.label"
      :prop="component.props.field"
      :label-position="component.props.labelPosition"
      :label-width="component.props.labelWidth"
      :style="labelTextStyle"
      :required="
        component.props.validationRule.required === true ||
        component.props.validationRule.required === 'true'
      "
      :rules="getInputRules(component)"
    >
      <el-input
        :model-value="component.value"
        :placeholder="component.props.placeholder"
        :disabled="component.props.disabled"
        :readonly="component.props.readonly "
        :maxlength="component.props.maxLength || undefined"
        :show-word-limit="component.props.showWordCount"
        @update:model-value="handleValueChange"
        @focus="handleFocus"
        @blur="handleBlur"
        @clear="handleValueChange('')"
        @click="handleElementClick"
      />
    </el-form-item>

    <!-- 文本域 -->
    <el-form-item
      v-else-if="component.type === 'textarea'"
      :label="component.props.label"
      :prop="component.props.field"
      :label-position="component.props.labelPosition"
      :label-width="component.props.labelWidth"
      :required="
        component.props.validationRule.required === true ||
        component.props.validationRule.required === 'true'
      "
      :rules="getInputRules(component)"
    >
      <el-input
        type="textarea"
        :model-value="component.value"
        :placeholder="component.props.placeholder"
        :rows="component.props.rows"
        :disabled="component.props.disabled"
        :readonly="component.props.readonly || !isPreview"
        :maxlength="component.props.maxLength || undefined"
        :show-word-limit="component.props.showWordCount"
        resize="none"
        @update:model-value="handleValueChange"
        @focus="handleFocus"
        @blur="handleBlur"
        @clear="handleValueChange('')"
        @click="handleElementClick"
      />
    </el-form-item>

    <!-- 单选框 -->
    <el-form-item
      v-else-if="component.type === 'radio'"
      :label="component.props.label"
      :prop="component.props.field"
      :label-position="component.props.labelPosition"
      :label-width="component.props.labelWidth"
      :required="
        component.props.validationRule.required === true ||
        component.props.validationRule.required === 'true'
      "
      :rules="getInputRules(component)"
    >
      <el-radio-group
        :model-value="component.value"
        :disabled="component.props.disabled"
        @update:model-value="handleValueChange"
        :class="
          component.props.layout === 'horizontal'
            ? 'horizontal-layout'
            : 'vertical-layout'
        "
      >
        <el-radio
          v-for="option in component.props.options"
          :key="option.value"
          :label="option.value"
        >
          {{ option.label }}
        </el-radio>
      </el-radio-group>
    </el-form-item>

    <!-- 多选框 -->
    <el-form-item
      v-else-if="component.type === 'checkbox'"
      :label="component.props.label"
      :prop="component.props.field"
      :label-position="component.props.labelPosition"
      :label-width="component.props.labelWidth"
      :required="
        component.props.validationRule.required === true ||
        component.props.validationRule.required === 'true'
      "
      :rules="getInputRules(component)"
    >
      <el-checkbox-group
        :model-value="component.value"
        :disabled="component.props.disabled"
        @update:model-value="handleValueChange"
        :class="
          component.props.layout === 'horizontal'
            ? 'horizontal-layout'
            : 'vertical-layout'
        "
      >
        <el-checkbox
          v-for="option in component.props.options"
          :key="option.value"
          :label="option.value"
        >
          {{ option.label }}
        </el-checkbox>
      </el-checkbox-group>
    </el-form-item>

    <!-- 下拉选择 -->
    <el-form-item
      v-else-if="component.type === 'select'"
      :label="component.props.label"
      :prop="component.props.field"
      :label-position="component.props.labelPosition"
      :label-width="component.props.labelWidth"
      :style="{
        color: 'red'
      }"
      :required="
        component.props.validationRule.required === true ||
        component.props.validationRule.required === 'true'
      "
      :rules="getInputRules(component)"
    >
      <div class="select-preview-container" @click="handleElementClick">
        <el-select
          :model-value="component.value"
          :placeholder="component.props.placeholder"
          :disabled="component.props.disabled"
          :readonly="true"
          clearable
          @update:model-value="handleValueChange"
          @focus="handleFocus"
          @blur="handleBlur"
          @click="handleElementClick"
          @clear="handleValueChange('')"
          @mousedown="handleElementClick"
          @mouseup="handleElementClick"
          @visible-change="handleSelectVisibleChange($event, component)"
          ref="selectRef"
        >
          <el-option
            v-for="option in component.props.options"
            :key="option.value"
            :label="option.label"
            :value="option.value"
            @click="handleElementClick"
          />
        </el-select>
      </div>
    </el-form-item>

    <!-- 日期选择 -->
    <el-form-item
      v-else-if="component.type === 'date'"
      :label="component.props.label"
      :prop="component.props.field"
      :label-position="component.props.labelPosition"
      :label-width="component.props.labelWidth"
      :required="
        component.props.validationRule.required === true ||
        component.props.validationRule.required === 'true'
      "
      :rules="getInputRules(component)"
    >
      <el-date-picker
        :model-value="component.value"
        :placeholder="component.props.placeholder"
        :disabled="component.props.disabled"
        :readonly="component.props.readonly"
        format="YYYY-MM-DD"
        value-format="YYYY-MM-DD"
        @update:model-value="handleValueChange"
        @clear="handleValueChange('')"
        @focus="handleFocus"
        @blur="handleBlur"
        @click="handleElementClick"
      />
    </el-form-item>

    <!-- 数字输入 -->
    <el-form-item
      v-else-if="component.type === 'number'"
      :label="component.props.label"
      :prop="component.props.field"
      :label-position="component.props.labelPosition"
      :label-width="component.props.labelWidth"
      :required="
        component.props.validationRule.required === true ||
        component.props.validationRule.required === 'true'
      "
      :rules="getInputRules(component)"
    >
      <el-input-number
        :model-value="component.value === '' ? undefined : component.value"
        :placeholder="component.props.placeholder"
        :min="component.props.min"
        :max="component.props.max"
        :step="component.props.step"
        :precision="component.props.precision"
        :disabled="component.props.disabled"
        :readonly="component.props.readonly"
        @update:model-value="handleValueChange"
        @clear="handleValueChange('')"
        @focus="handleFocus"
        @blur="handleBlur"
        @click="handleElementClick"
      />
    </el-form-item>

    <!-- 分割线 -->
    <el-divider v-else-if="component.type === 'divider'" :style="dividerStyle">
      {{ component.props.label }}
    </el-divider>

    <!-- 静态文本 -->
    <div
      v-else-if="component.type === 'text'"
      class="static-text"
    >
      <strong :style="labelTextStyle">{{ component.props.label }}</strong>
      <span :style="contentTextStyle">{{ component.props.content }}</span>
    </div>

    <!-- 栅格布局 -->
    <div
      v-else-if="component.type === 'grid'"
      class="grid-layout"
      :class="[`direction-${component.props.direction}`]"
      :style="{ gap: component.props.gridGap }"
    >
      <div
        v-for="(gridItem, index) in component.props.gridItems"
        :key="index"
        :class="[
          'grid-item',
          {
            'grid-item-hover': isGridItemHovered(index),
            'grid-item-select': isGridItemSelected(index),
          },
        ]"
        :style="{
          border: component.props.showGridBorder
            ? `1px ${component.props.gridBorderStyle || 'dashed'} ${
                component.props.gridBorderColor || '#e4e7ed'
              }`
            : 'none',
          borderRadius: `${component.props.borderRadius || 4}px`,
        }"
      >
        <div class="grid-item-content">
          <!-- 渲染栅格内的子组件 -->
          <div
            v-if="component.children && component.children.length > 0"
            class="grid-children"
          >
            <div
              v-for="childComponent in getGridChildren(component, index)"
              :key="childComponent.id"
              class="grid-child-wrapper"
            >
              <!-- 栅格子组件工具栏 -->
              <ComponentToolbar
                v-if="!isPreview && selectedComponent?.id === childComponent.id"
                :component="childComponent"
                :variant="'floating'"
                class="grid-child-toolbar"
              />
              <FormComponent
                :component="childComponent"
                :selectedComponent="selectedComponent"
                :mutex-state="mutexState"
                :relate-state="relateState"
                :is-preview="isPreview"
                @click.stop="handleChildClick(childComponent, $event as Event)"
                @select-component="handleGridChildSelect"
              />
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts" name="FormComponent">
import { computed, ref, nextTick } from "vue";
import type { CanvasComponent, RelateConfig } from "../types";
import ComponentToolbar from "./ComponentToolbar.vue";
import { EventBus } from "@/utils/eventBus";

interface Props {
  component: CanvasComponent;
  mutexState?: Map<string, boolean>;
  relateState?: RelateConfig[];
  isPreview?: boolean;
  dragHoverState?: {
    isHovering: boolean;
    gridComponent: CanvasComponent | null;
    gridItemIndex: number;
  };
  selectedComponent?: CanvasComponent | null;
}

const props = withDefaults(defineProps<Props>(), {
  mutexState: () => new Map(),
  relateState: () => [],
  isPreview: false,
  dragHoverState: () => ({
    isHovering: false,
    gridComponent: null,
    gridItemIndex: -1,
  }),
  selectedComponent: null,
});

const emit = defineEmits<{
  "select-component": [component: CanvasComponent, event: Event];
  "update:model-value": [value: any];
  "value-change": [field: string, value: any];
  "select-visible-change": [visible: boolean, component: CanvasComponent];
  "grid-hover": [isHovering: boolean, component: CanvasComponent, index: number];
  "grid-select": [component: CanvasComponent, index: number];
  "grid-clear-selection": [];
  "grid-child-select": [component: CanvasComponent, event: Event];
  "grid-child-delete": [componentId: string];
  "grid-child-copy": [component: CanvasComponent];
  "grid-child-open-mutex": [component: CanvasComponent];
  "grid-child-cancel-mutex": [component: CanvasComponent];
  "grid-child-open-relate": [component: CanvasComponent];
  "grid-child-value-change": [field: string, value: any];
}>();

// 获取输入类组件的验证规则
const getInputRules = (component: CanvasComponent) => {
  const rules: any[] = [];
  // 只有当 required 为 true 时才添加必填验证（处理字符串和布尔值）
  if (
    component.props.validationRule.required === true ||
    component.props.validationRule.required === "true"
  ) {
    rules.push({
      required: true,
      message: ['radio', 'checkbox', 'select'].includes(component.type) ? "请选择" : "请输入",
      trigger: ['radio', 'checkbox', 'select'].includes(component.type) ? "change" : "blur",
    });
  }

  // 长度验证（如果设置了最小或最大长度）
  if (component.props.minLength > 0 || component.props.maxLength > 0) {
    rules.push({
      min: component.props.minLength || 0,
      max: component.props.maxLength || 999,
      message: `长度在 ${component.props.minLength || 0} 到 ${
        component.props.maxLength || 999
      } 之间`,
      trigger: "blur",
    });
  }
  // 正则验证
  if (component.props.pattern) {
    rules.push({  
      message: component.props.patternMessage || "输入内容不符合正则表达式",
      pattern: new RegExp(component.props.pattern),
      trigger: "blur",
    });
  }

  return rules;
};


// 移除递归的异步组件定义，避免组件实例创建问题

// 删除状态标志
const isDeleting = ref(false);

// select组件引用
const selectRef = ref();

// 计算组件样式
const componentStyle = computed(() => {
  const style: Record<string, any> = {
    width: "100%",
    height: "100%",
    display: "flex",
    flexDirection: "column",
    justifyContent: "center",
  };

  // 普通组件的样式处理
  // 应用宽度设置
  if (
    props.component.props.widthType === "custom" &&
    props.component.props.customWidth
  ) {
    style.width = `${props.component.props.customWidth}px`;
  } else if (props.component.props.widthType === "full") {
    style.width = "100%";
  }

  // 应用字体样式
  if (props.component.props.fontSize) {
    style.fontSize = `${props.component.props.fontSize}px`;
  }
  if (props.component.props.color) {
    style.color = props.component.props.color;
  }
  if (props.component.props.backgroundColor) {
    style.backgroundColor = props.component.props.backgroundColor;
  }

  // 应用边框样式
  if (
    props.component.props.borderStyle &&
    props.component.props.borderStyle !== "none"
  ) {
    style.border = `${props.component.props.borderWidth || 1}px ${
      props.component.props.borderStyle
    } ${props.component.props.borderColor || "#dcdfe6"}`;
  }

  // 应用圆角
  if (props.component.props.borderRadius !== undefined) {
    style.borderRadius = `${props.component.props.borderRadius}px`;
  }

  // 应用内边距和外边距
  if (
    props.component.props.padding !== undefined &&
    props.component.props.padding > 0
  ) {
    style.padding = `${props.component.props.padding}px`;
  }
  if (
    props.component.props.margin !== undefined &&
    props.component.props.margin > 0
  ) {
    style.margin = `${props.component.props.margin}px`;
  }

  return style;
});

// 计算分割线样式
const dividerStyle = computed(() => {
  const style: Record<string, any> = {};

  if (props.component.props.color) {
    style.borderColor = props.component.props.color;
  }
  if (props.component.props.borderWidth) {
    style.borderWidth = `${props.component.props.borderWidth}px`;
  }

  style.margin= '10px 0px'
  return style;
});

// 计算文本样式
const labelTextStyle = computed(() => {
  const style: Record<string, any> = {
    padding: "8px 0",
  };

  if (props.component.props.fontSize) {
    style.fontSize = `${props.component.props.fontSize}px`;
  }
  if (props.component.props.color) {
    style.color = props.component.props.color;
  }

  if(props.component.props.labelPosition === 'top' && props.component.type == 'text') {
    style.display = 'flex'
    style.flexDirection = 'column'
  }
  return style;
});

const contentTextStyle = computed(() => {
  const style: Record<string, any> = {
    padding: "8px 0",
  };

  // 字体大小
  if (props.component.props.textFontSize) {
    style.fontSize = `${props.component.props.textFontSize}px`;
  }
  
  // 字体颜色 - 优先使用textColor，备用color
  if (props.component.props.textColor) {
    style.color = props.component.props.textColor;
  } 
  
  // 字体粗细
  if (props.component.props.fontWeight) {
    style.fontWeight = props.component.props.textFontWeight;
  }

  return style;
});
// 检查是否被互斥规则隐藏
const isHiddenByMutex = computed(() => {
  return props.mutexState.get(props.component.id) || false;
});

// 检查当前组件是否被选中
const isSelected = computed(() => {
  return props.selectedComponent?.id === props.component.id;
});

// 处理值变化
const handleValueChange = (value: any) => {
  console.log("FormComponent handleValueChange", value, props.component);
  // 设计模式下，将值置空
  if (!props.isPreview) {
    if (typeof value === "string") {
      props.component.value = "";
      nextTick(() => {
        EventBus.emit("component-value-change", {
          field: props.component.props.field,
          value: '',
          componentId: props.component.id,
        });
      });
    } else if (Array.isArray(value)) {
      // 多选框等数组类型组件，设置为空数组
      props.component.value = [];
      nextTick(() => {
        EventBus.emit("component-value-change", {
          field: props.component.props.field,
          value: [],
          componentId: props.component.id,
        });
      });
    } else if (typeof value === "object") {
      props.component.value = {};
      nextTick(() => {
        EventBus.emit("component-value-change", {
          field: props.component.props.field,
          value: {},
          componentId: props.component.id,
        });
      });
    }
    return;
  }

  // 对于数字输入组件，如果值为 undefined 或 null，则设置为空字符串
  let finalValue = value;
  if (
    props.component.type === "number" &&
    (value === undefined || value === null)
  ) {
    finalValue = "";
  }

  // 直接更新组件值
  props.component.value = finalValue;

  // // 执行内置验证
  // const validationRule = props.component.props.validationRule;
  // if (validationRule && validationRule.type !== "none") {
  //   const validationResult = validateValue(finalValue, validationRule.type);
  //   if (!validationResult.isValid && "message" in validationResult) {
  //     console.warn(
  //       `组件 ${props.component.props.label} 验证失败: ${validationResult.message}`
  //     );
  //     // 这里可以显示错误消息，比如使用 Element Plus 的 Message 组件
  //   }
  // }

  // 执行值变化事件
  if (props.component.props.onChange) {
    try {
      const changeFn = new Function("value", props.component.props.onChange);
      changeFn(finalValue);
    } catch (error) {
      console.error("值变化事件执行错误:", error);
    }
  }
  // setComponentOptions(finalValue);
  // 触发值更新事件
  // emit('update-value', finalValue);
  nextTick(() => {
    EventBus.emit("component-value-change", {
      field: props.component.props.field,
      value: finalValue,
      componentId: props.component.id,
    });
  });
};

// 选中子组件
const handleChildClick = (childComponent: CanvasComponent, event: Event) => {
  console.log("当前选中的子组件:", props.selectedComponent);
  if (props.isPreview) return;
  event.stopPropagation();
  event.preventDefault();
  // 在删除过程中不触发选中事件
  if (!isDeleting.value) {
    emit("select-component", childComponent, event);
  }
};

const handleClick = () => {
  if (props.component.props.onClick) {
    try {
      const clickFn = new Function(props.component.props.onClick);
      clickFn();
    } catch (error) {
      console.error("点击事件执行错误:", error);
    }
  }
};

const handleFocus = () => {
  if (props.component.props.onFocus) {
    try {
      const focusFn = new Function(props.component.props.onFocus);
      focusFn();
    } catch (error) {
      console.error("焦点事件执行错误:", error);
    }
  }
};

const handleBlur = () => {
  if (props.component.props.onBlur) {
    try {
      const blurFn = new Function(props.component.props.onBlur);
      blurFn();
    } catch (error) {
      console.error("失焦事件执行错误:", error);
    }
  }
};

// 处理select下拉框显示状态变化
const handleSelectVisibleChange = (
  visible: boolean,
  component: CanvasComponent
) => {
  // 如果下拉框关闭，清空组件值但不做任何校验
  if (!visible) {
    // 清空组件值，但不触发任何校验或互斥检查
    // component.value = ''
    console.log("下拉框已关闭，组件值已清空:", component.props.label);
  }
};

// 处理表单元素点击事件
const handleElementClick = (event: Event) => {
  // 在预览模式下，允许正常的表单交互
  if (props.isPreview) {
    return;
  }

  // 阻止默认事件，防止触发画布的拖拽等操作
  event.preventDefault();
  event.stopPropagation();
  event.stopImmediatePropagation();

  // 在删除过程中不触发选中事件
  if (!isDeleting.value) {
    // 触发组件选中事件
    emit("select-component", props.component, event);
  }
};

// 获取栅格中指定列的子组件
const getGridChildren = (
  gridComponent: CanvasComponent,
  columnIndex: number
): CanvasComponent[] => {
  if (!gridComponent.children) return [];
  return gridComponent.children.filter(
    (child) => child.gridItemIndex === columnIndex
  );
};

// 检查栅格项是否处于悬停状态
const isGridItemHovered = (index: number): boolean => {
  return (
    props.dragHoverState.isHovering &&
    props.dragHoverState.gridComponent?.id === props.component.id &&
    props.dragHoverState.gridItemIndex === index
  );
};

const isGridItemSelected = (index: number): boolean => {
  if (!props.component.children) return false;
  // 获取当前栅格项的子组件
  const gridChildren = getGridChildren(props.component, index);
  // 判断是否有子组件被选中
  return gridChildren.some((child) => child.id === props.selectedComponent?.id);
};

// 处理栅格内子组件的选中
const handleGridChildSelect = (
  childComponent: CanvasComponent,
  event: Event
) => {
  console.log("栅格内子组件选中事件:", childComponent);

  // 在删除过程中不触发选中事件
  if (!isDeleting.value) {
    emit("select-component", childComponent, event);
  }
};
</script>

<style scoped lang="scss">
.form-component {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: center;

  .static-text {
    padding: 8px 0;

    strong {
      margin-right: 8px;
      color: #303133;
    }

    span {
      color: #606266;
    }
  }
}

// 全局样式调整
:deep(.el-form-item) {
  margin-bottom: 0;
  width: 100%;

  .el-form-item__content {
    width: 100%;
  }
}

:deep(.el-form-item__label) {
  font-weight: 500;
  color: inherit;
  font-size: inherit;
}

// 纵向布局（默认）
:deep(.el-radio-group.vertical-layout) {
  display: flex;
  flex-direction: column;
  gap: 8px;
  align-items: flex-start;
}

:deep(.el-checkbox-group.vertical-layout) {
  display: flex;
  flex-direction: column;
  gap: 8px;
  align-items: flex-start;
}

// 横向布局
:deep(.el-radio-group.horizontal-layout) {
  display: flex;
  flex-direction: row;
  gap: 16px;
  align-items: center;
  flex-wrap: wrap;
}

:deep(.el-checkbox-group.horizontal-layout) {
  display: flex;
  flex-direction: row;
  gap: 16px;
  align-items: center;
  flex-wrap: wrap;
}

:deep(.el-checkbox) {
  margin-right: 8px;
}

:deep(.el-select) {
  width: 100%;
}

:deep(.el-date-editor) {
  width: 100%;
}

:deep(.el-input-number) {
  width: 100%;
}

// 栅格布局样式
.grid-layout {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  gap: 16px;
  outline: none;
  &.direction-horizontal {
    flex-direction: row;
  }

  &.direction-vertical {
    flex-direction: column;
  }
  .grid-item {
    flex: 1;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: flex-start;
    transition: all 0.3s;
    outline: none;
    &:hover {
      background-color: #f5f7fa;
    }

    &.grid-item-hover {
      border: 2px solid #67c23a !important;
      box-shadow: 0 0 8px rgba(103, 194, 58, 0.4);
      transform: scale(1.01);
    }

    &.grid-item-select {
      .form-component {
        outline: 1px dashed #409eff; // 选中时显示更明显的轮廓
      }
    }

    .grid-item-content {
      width: 100%;
      display: flex;
      align-items: center;
      gap: 8px;
      outline: none !important;

      .grid-item-label {
        font-size: 14px;
        color: #909399;
        font-weight: 500;
        margin-bottom: 8px;
      }

      .grid-children {
        width: 100%;
        display: flex;
        flex-direction: column;
      }

      .grid-child-wrapper {
        position: relative;
        width: 100%;
      }

      .grid-child-toolbar {
        position: absolute;
        top: 55px;
        right: -2px;
        bottom: -26px;
        z-index: 1000;
        border-radius: 4px;
      }
    }

    .grid-children {
      gap: 8px;
      outline: none !important;

      .form-component {
        width: 100%;
        margin: 0;
        position: relative;
        cursor: pointer;
        border-radius: 4px;

        &:hover {
          outline: 1px dashed #409eff;
          border-color: #409eff;
        }

        &.selected {
          border: 1px dashed #409eff;
          box-shadow: 0 0 8px rgba(64, 158, 255, 0.3);
        }
      }
    }
  }
}

.select-preview-container {
  width: 100%;
  display: flex;
}

:deep(.el-input__wrapper) {
  width: 100%;
}
</style>
